<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    产生闭包的条件
        1. 函数嵌套
        2. 内部函数引用了外部函数的局部变量
        3. 调用外部
    什么时候创建? 
        执行内部函数定义, 也就是创建内部函数对象
    闭包是什么?
        是包含了被引用变量的一个容器(不是js对象), 被内部函数对象引用着
        fn2 ==> 内部函数对象 ==> 闭包
    如何使用闭包? / 如何让闭包在执行完函数后还能存活下来?
        返回内部函数, 在外部接收    最常用的手段
        用其它不会立即释放的变量引用内部函数对象  setTimeout(() => {})
    闭包的作用?
        延长局部变量的生命周期
        让函数外部能间接操作内部的局部变量
    区别闭包的三个操作
        产生闭包:  内部函数对象创建时产生, 包含那个被引用的变量的容器(不是js对象)
        使用闭包: 执行内部函数
        释放闭包: 让内部函数对象成为垃圾对象, 断开指向它的所有引用
    闭包的应用?
        具体功能说: 可以说根据id删除品牌(需要显示确定框)
        大的说: 我们定义的很多模块在编译后的代码中都存在闭包
    
    */
    function fn1() {
        var a = 2
        function fn2() { // fn2是指向内部函数对象的一个局部变量
            a++
            console.log(a)
        }
        return fn2
    }
    
    var f = fn1()   // f =》局部函数对象 =》闭包 =》内部有a
    // 此时fn2是否还存在？==》 不存在了   a存在吗？
    f() // 3
    f() // 4

    f = null  // 释放闭包
    // f = 1  //是否可以让闭包释放？


    function showDelay(msg, time) {
        setTimeout(() => {  // setTimeout内部保存着内部函数对象
            console.log(msg)
        }, time);
    }
    showDelay('atguigu', 1000)


    function fn() {
        var data = 123

        function increment(count) {
            data += count
        }
        return increment
    }
    var f = fn()
    f(2)

  </script>

  <script>
    /* 测试题 */
    // 题1
    
    /*  for ( var i = 0 ; i < 5; i++ ) {
            setTimeout(function(){
                console.log(i);
            }, 0);
        } 
        */
    // 55555

    // 题2
    /*  for ( let i = 0 ; i < 5; i++ ) {
            setTimeout(function(){
                console.log(i);
            },0);
        } */
        // 01234 
    

    // 题3
    /* for ( var i = 0 ; i < 5; i++ ) {
        (function(j){
            setTimeout(function(){
                console.log(j);
            }, 0);
        })(i);
    }  */
    // 01234
    


    // 题4
    /* 
    var scope = 'global scope'
    function checkscope(){
        var scope = 'local scope'
        return function f(){
            console.log(scope)
        }
    }
    var f = checkscope()
    console.log(f()) // local scope  / undfined
    */

    // 题5
    /* 
    var name = 'jerry'
    var obj = {  
        name : 'tom',  
        sayName(){ 
            console.log(this.name)  // tom
            return function(){  
                console.log(this.name);  // jerry
            }
        }   
    }
    obj.sayName()() 
    */
  </script>
</body>
</html>